package com.cloudeasy.post.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudeasy.api.enums.ResultCodeEnum;
import com.cloudeasy.api.exception.CloudEasyException;
import com.cloudeasy.api.util.SnowFlake;
import com.cloudeasy.api.vo.post.PushVO;
import com.cloudeasy.api.vo.post.SimpleUserInfoVO;
import com.cloudeasy.post.dao.mapper.ReplyMapper;
import com.cloudeasy.post.dto.ReviewDTO;
import com.cloudeasy.post.po.Reply;
import com.cloudeasy.post.service.expand.PushService;
import com.cloudeasy.post.service.expand.SimpleUserInfoService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class ReplyService extends ServiceImpl<ReplyMapper, Reply> {
    private final PostService postService;

    private final StoreyService storeyService;

    private final SnowFlake snowFlake;

    private final SimpleUserInfoService simpleUserInfoService;

    private final PushService pushService;

    public ReplyService(@Lazy PostService postService, @Lazy StoreyService storeyService, SnowFlake snowFlake, SimpleUserInfoService simpleUserInfoService, PushService pushService) {
        this.postService = postService;
        this.storeyService = storeyService;
        this.snowFlake = snowFlake;
        this.simpleUserInfoService = simpleUserInfoService;
        this.pushService = pushService;
    }

    /**
     * 根据帖子Id删除记录
     *
     * @param postId 帖子Id
     * @return {@link Boolean}
     */
    public Boolean removeByPostId(String postId) {
        QueryWrapper<Reply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", postId);

        List<String> replyIds = this.list(queryWrapper).stream().map(Reply::getId).collect(Collectors.toList());
        storeyService.removeByReplyIds(replyIds);

        return this.remove(queryWrapper);
    }

    /**
     * 评论
     *
     * @param postId     帖子Id
     * @param reviewerId 评论者Id
     * @param reviewDTO  {@link ReviewDTO}
     * @return {@link Boolean}
     */
    public Boolean save(String postId, String reviewerId, ReviewDTO reviewDTO) {
        String authorId = postService.review(postId);
        // 推送
        SimpleUserInfoVO reviewer = simpleUserInfoService.obtainSimpleUserInfo(Collections.singletonList(reviewerId)).get(0);
        PushVO pushVO = PushVO.builder()
                .message(String.format("%s 评论了您的帖子", reviewer.getNickname()))
                .responseId(postId)
                .responder(reviewer)
                .type(0)
                .pushDate(new Date())
                .build();
        pushService.push(authorId, pushVO);
        String id = String.valueOf(snowFlake.nextId());
        Reply reply = Reply.builder()
                .id(id)
                .postId(postId)
                .reviewerId(reviewerId)
                .content(reviewDTO.getContent())
                .build();
        return this.save(reply);
    }

    /**
     * 删除评论
     *
     * @param reply {@link Reply}
     * @return {@link Boolean}
     */
    public Boolean removeById(Reply reply) {
        postService.removeReview(reply.getPostId());

        storeyService.removeByReplyIds(Collections.singletonList(reply.getId()));

        return this.removeById(reply.getId());
    }

    /**
     * 根据评论Id查询记录
     *
     * @param reviewerId 评论者Id
     * @return {@link List<Reply>}
     */
    public List<Reply> listByReviewerId(String reviewerId) {
        QueryWrapper<Reply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("reviewer_id", reviewerId)
                .orderByDesc("reply_time");
        return this.list(queryWrapper);
    }

    /**
     * 根据评论Id分页查询记录
     *
     * @param reviewerId 评论者Id
     * @param page       页数
     * @param size       每页大小
     * @return {@link IPage<Reply>}
     */
    public IPage<Reply> pageByReviewerId(String reviewerId, Integer page, Integer size) {
        QueryWrapper<Reply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("reviewer_id", reviewerId)
                .orderByDesc("reply_time");
        IPage<Reply> replyIPage = new Page<>();
        replyIPage.setCurrent(page).setSize(size);
        return this.page(replyIPage, queryWrapper);
    }

    /**
     * 根据帖子Id分页查询记录
     *
     * @param postId 帖子Id
     * @param page   页数
     * @param size   每页大小
     * @return {@link IPage<Reply>}
     */
    public IPage<Reply> pageByPostId(String postId, Integer page, Integer size) {
        QueryWrapper<Reply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", postId)
                .orderByAsc("reply_time");
        IPage<Reply> replyIPage = new Page<>();
        replyIPage.setCurrent(page).setSize(size);
        return this.page(replyIPage, queryWrapper);
    }

    /**
     * 回复处理逻辑
     *
     * @param replyId 评论Id
     * @return 评论用户Id
     */
    public String answer(String replyId) {
        Reply reply = this.getById(replyId);
        if (reply == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }

        reply.setStorey(true);
        this.updateById(reply);
        return reply.getReviewerId();
    }

    /**
     * 点赞评论
     *
     * @param replyId 评论Id
     * @param type    类型
     * @return {@link Boolean}
     */
    public Boolean like(String replyId, Integer type) {
        Reply reply = this.getById(replyId);
        if (reply == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        updateLike(reply, type, 1);
        return this.updateById(reply);
    }

    /**
     * 取消点赞评论
     *
     * @param replyId 评论Id
     * @param type    类型
     * @return {@link Boolean}
     */
    public Boolean removeLike(String replyId, Integer type) {
        Reply reply = this.getById(replyId);
        if (reply == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        updateLike(reply, type, -1);
        return this.updateById(reply);
    }

    /**
     * 更新评论数据
     *
     * @param reply 评论
     * @param type  点赞类型
     * @param inc   变更值
     */
    public void updateLike(Reply reply, Integer type, int inc) {
        switch (type) {
            case 1:
                reply.setAsBadReviewCount(reply.getAsBadReviewCount() + inc);
                break;
            case 2:
                reply.setAsWaterCount(reply.getAsWaterCount() + inc);
                break;
            case 3:
                reply.setAsSuggestCount(reply.getAsSuggestCount() + inc);
                break;
            case 4:
                reply.setAsStrategyCount(reply.getAsStrategyCount() + inc);
                break;
            case 5:
                reply.setAsGodReplyCount(reply.getAsGodReplyCount() + inc);
                break;
            case 6:
                reply.setAsTeasingCount(reply.getAsTeasingCount() + inc);
                break;
            default:
                break;
        }
        long[] count = new long[7];
        count[1] = reply.getAsBadReviewCount();
        count[2] = reply.getAsWaterCount();
        count[3] = reply.getAsSuggestCount();
        count[4] = reply.getAsStrategyCount();
        count[5] = reply.getAsGodReplyCount();
        count[6] = reply.getAsTeasingCount();
        long maxVal = count[0];
        int maxIndex = 0;
        for (int i = 0; i < count.length; i++) {
            if (count[i] > maxVal) {
                maxVal = count[i];
                maxIndex = i;
            }
        }
        reply.setType(maxIndex);
    }
}
